#ifndef GAMEENGINE_GEOMETRY_CIRCLE3D_H
#define GAMEENGINE_GEOMETRY_CIRCLE3D_H

#include <GameEngine/Geometry/geometry_settings.h>

#include <GameEngine/Geometry/Location/point3d.h>
#include <GameEngine/Geometry/Location/vector3d.h>
#include <GameEngine/Geometry/Lines/line3d.h>
#include <GameEngine/Geometry/Core/angle.h>
#include <GameEngine/Geometry/Surfaces/plane3d.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//! Class used to represent 3D circles
/*!
 @note A circle is a 2D object embedded in a 3D space, represented by its center,
       its radius and a normal orientation
 @note Most algorithms expect floating point operations. Type T should therefore
       not be an integer type
 */
template <class T>
class Circle3d {

public:
	Circle3d();
	Circle3d(const Point3d<T>& center, const T& radius, const Vector3d<T>& normal);
	Circle3d(const Circle3d& rhs);
	virtual ~Circle3d();
	Circle3d& operator=(const Circle3d& rhs);

	Point3d<T>& center();
	const Point3d<T>& center() const;
	T& radius();
	const T& radius() const;
	Vector3d<T>& normal();
	const Vector3d<T>& normal() const;

	T diameter() const;
	T area() const;

	bool coplanar(const Point3d<T>& rhs, const T& tolerance = 0.000001) const;
	bool inside(const Point3d<T>& rhs, bool strict = false) const;
	int intersection(const Line3d<T>& rhs, T& coordinate1, T& coordinate2, IntersectionType::Type* type = nil) const;

	Point3d<T> closest_point(const Point3d<T>& rhs) const;

	Plane3d<T> plane() const;

protected:
	//! Center of the circle
	Point3d<T> center_;

	//! Radius of the circle
	T radius_;

	//! Normal of the circle
	Vector3d<T> normal_;
};

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#include <GameEngine/Geometry/Surfaces/circle3d.hpp>

#endif
